import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { CreateMenuDto } from './dto/create-menu.dto';
import { UpdateMenuDto } from './dto/update-menu.dto';
import { QueryMenuDto } from './dto/query-menu.dto';
import { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';
import { EntityManager, In, Like, Repository } from 'typeorm';
import { Menu } from './entities/menu.entity';
import { Request } from 'express';
import { User } from 'src/system/user/entities/user.entity';
import { UserRoleService } from 'src/system/user-role/user-role.service';

@Injectable()
export class MenuService {
  constructor(
    @InjectRepository(Menu) private readonly menu: Repository<Menu>,
    @InjectEntityManager() private readonly entityManager: EntityManager,
    private readonly userRoleService: UserRoleService,
  ) {}
  create(createMenuDto: CreateMenuDto, request: Request) {
    let user = request.user as User;
    createMenuDto.create_by = user.username;
    return this.menu.save(createMenuDto);
  }

  async findAll(id: number, query: QueryMenuDto) {
    // 根据用户id查找对应的角色id数组
    const roles = await this.userRoleService.getRoleIdByUser(id);
    let menus: Menu[] = [];

    // 拼接查询条件
    let whereConditions: QueryMenuDto = {};
    if (query.menu_name) {
      whereConditions.menu_name = Like(`%${query.menu_name}%`);
    }
    if (query.status) {
      whereConditions.status = query.status;
    }
    // 如果角色id中有1，表示角色是超级管理员，直接获取所有菜单
    if (roles.includes(1)) {
      menus = await this.menu.find({
        where: whereConditions,
        order: {
          parent_id: 'ASC',
          order_num: 'ASC',
        },
      });
    } else {
      const menuIds = await this.entityManager
        .createQueryBuilder()
        .select('menu_id')
        .from('role_menu', 'rm')
        .where('rm.role_id IN (:...roles)', { roles })
        .getRawMany(); // 获取所有匹配的 menu_id

      // 使用获取的 menu_id 数组来过滤菜单
      let qb = await this.entityManager
        .createQueryBuilder(Menu, 'm')
        .where('m.menu_id IN (:...menuIds)', {
          menuIds: menuIds.map((item) => item.menu_id),
        })
        if(query.menu_name) {
          qb = qb.andWhere('m.menu_name LIKE :menuName', {
            menuName: `%${query.menu_name}%`,
          })
        }
        if(query.status) {
          qb = qb.andWhere('m.status = :status', {status:`${query.status}`})
        }
        menus = await qb.getMany();
    }
    return menus;
  }

  findOne(id: number) {
    return this.menu.findOne({ where: { menu_id: id } });
  }

  update(menu_id: number, updateMenuDto: UpdateMenuDto, request: Request) {
    let user = request.user as User;
    updateMenuDto.update_by = user.username;
    return this.menu.update(menu_id, updateMenuDto);
  }

  /**
   * 删除菜单
   * @param menu_id
   */
  async remove(menu_id: number) {
    let children = await this.menu.find({ where: { parent_id: menu_id } });
    if(children && children.length > 0) {
      throw new HttpException('该菜单下有子菜单，不能删除',HttpStatus.BAD_REQUEST)
    }
    return this.menu.delete(menu_id);
  }

  /**
   * 根据角色获取所有菜单
   * @param id
   */
  async getMenus(id: number) {
    const roles = await this.userRoleService.getRoleIdByUser(id);
    let menus: Menu[] = [];
    // 如果角色id中有1，表示角色是超级管理员，直接获取所有菜单
    if (roles.includes(1)) {
      menus = await this.menu.find({
        where:{
          menu_type: In(['M','C'])
        },
        order: {
          parent_id: 'ASC',
          order_num: 'ASC',
        },
      });
    } else if(roles && roles.length > 0) {
      const menuIds = await this.entityManager
        .createQueryBuilder()
        .select('menu_id')
        .from('role_menu', 'rm')
        .where('rm.role_id IN (:...roles)', { roles })
        .getRawMany(); // 获取所有匹配的 menu_id

      // 使用获取的 menu_id 数组来过滤菜单
      menus = await this.entityManager
        .createQueryBuilder(Menu, 'm')
        .where('m.menu_id IN (:...menuIds)', {
          menuIds: menuIds.map((item) => item.menu_id),
        })
        .andWhere("m.menu_type != 'F'")
        .getMany();
    }
    return menus;
  }

  /**
   * 根据角色获取所有权限
   * @param id
   */
  async getPerms(id: number) {
    const roles = await this.userRoleService.getRoleIdByUser(id);
    let perms: Menu[] | string[] = [];
    // 如果角色id中有1，表示角色是超级管理员，直接获取所有菜单
    if (roles.includes(1)) {
      perms = ["*:*:*"]
      return perms
    } else {
      const menuIds = await this.entityManager
        .createQueryBuilder()
        .select('menu_id')
        .from('role_menu', 'rm')
        .where('rm.role_id IN (:...roles)', { roles })
        .getRawMany(); // 获取所有匹配的 menu_id

      // 使用获取的 menu_id 数组来过滤菜单
      perms = await this.entityManager
        .createQueryBuilder(Menu, 'm')
        .where('m.menu_id IN (:...menuIds)', {
          menuIds: menuIds.map((item) => item.menu_id),
        })
        .getMany();
        return perms.map(k => k.perms).filter(k => k);
    }
  }
}
